<?php
#
# REQUIRE
#
require_once dirname(__FILE__).'/__l.Export.php';

#
# CSRF
#
function nonce() {
	return md5(session_id());
}

function nonce_name() {
	return md5(session_name());
}

#
# USER
#
function is_authenticated() {
	return isset($_SESSION['user.ID']);
}

function authenticate($user_id, $data = array()) {
	$_SESSION['user.ID'] = $user_id;
	$_SESSION['user.data'] = $data;
}

function deauthenticate() {
	unset($_SESSION['user.ID']);
	unset($_SESSION['user.data']);
}

#
# EXPORT HELPERS
#
function data($data) {
	return success(array('data' => $data));
}

function success($data = array()) {
	return array_merge(array('status' => true), $data);
}

function failure($data = array()) {
	return array_merge(array('status' => false), $data);
}

#
# NORMAL ERROR HELPERS
#
function problem($message, $desc = '') {
	global $CONFIG;
	
	if (!$CONFIG['error.verbose']) {
		return failure(array('error' => array('message' => $message)));
	} else {
		return failure(array('error' => array('message' => $message, 'description' => $desc)));
	}
}

function noparam($name) {
	return problem("parameter '".$name."' was not found!");
}

#
# EXITING ERROR HELPERS
#
function fault($code, $message) {
	header('HTTP/1.1 '.str_replace(array('\n', '\r', '\r\n', '\n\r'), '', $code.' '.$message));

	#
	# EXCUTE HANDLER FINISH
	#
	if (function_exists('handler_finish')) {
		call_user_func('handler_finish');
	}

	exit;
}

function error($message, $desc = '') {
	global $CONFIG;

	if (!$CONFIG['error.verbose']) {
		export(failure(array('error' => array('message' => $message))));
	} else {
		export(failure(array('error' => array('message' => $message, 'description' => $desc))));
	}

	#
	# EXCUTE HANDLER FINISH
	#
	if (function_exists('handler_finish')) {
		call_user_func('handler_finish');
	}

	exit;
}

#
# REDIRECTING HELPERS
#
function redirect($url) {
	header('Location: '.str_replace(array('\n', '\r', '\r\n', '\n\r'), '', $url));

	#
	# EXCUTE HANDLER FINISH
	#
	if (function_exists('handler_finish')) {
		call_user_func('handler_finish');
	}

	exit;
}

function labeled_redirect($label) {
	global $CONFIG;

	return redirect($CONFIG['redirect.labels'][$label]);
}

function register_labeled_redirect($label, $url) {
	global $CONFIG;

	$CONFIG['redirect.labels'][$label] = $url;
}

#
# CALLS
#
function call($service, $action, $params = array()) {
	return webcall($service, $action, $params);
}

function webcall($service, $action, $params = array(), $url = null) {
	global $CONFIG;

	if (!isset($url)) {
		$url = $CONFIG['monka.url'];
	}

	$params['_service'] = $service;
	$params['_action'] = $action;
	$params['_output'] = 'serialized';

	foreach ($params as $key => $value) {
		$tmp[] = urlencode($key).'='.urlencode($value);
	}

	$content = file_get_contents($url.'?'.implode('&', $tmp));

	return unserialize($content);
}

#
# BASE INCLUDE/REQUIRE
#
function base_require($file) {
	global $CONFIG;

	require $CONFIG['monka.path'].'/'.$file;
}

function base_require_once($file) {
	global $CONFIG;

	require_once $CONFIG['monka.path'].'/'.$file;
}

function base_include($file) {
	global $CONFIG;

	include $CONFIG['monka.path'].'/'.$file;
}

function base_include_once($file) {
	global $CONFIG;

	include_once $CONFIG['monka.path'].'/'.$file;
}

#
# CASCADING INCLUDE/REQUIRE
#
function cascading_require($file, $blocking = false) {
	global $CONFIG;
	global $PARAMS;

	$found = false;

	if (isset($CONFIG['monka.path.includes']) && is_array($CONFIG['monka.path.includes'])) {
		foreach ($CONFIG['monka.path.includes'] as $path) {
			$path = trim($path);

			if (is_file(realpath($path.'/'.$file))) {
				require realpath($path.'/'.$file);

				if ($blocking) {
					return true;
				} else {
					$found = true;
				}
			}
		}
	}

	return $found;
}

function cascading_require_once($file, $blocking = false) {
	global $CONFIG;
	global $PARAMS;

	$found = false;

	if (isset($CONFIG['monka.path.includes']) && is_array($CONFIG['monka.path.includes'])) {
		foreach ($CONFIG['monka.path.includes'] as $path) {
			$path = trim($path);

			if (is_file(realpath($path.'/'.$file))) {
				require_once realpath($path.'/'.$file);

				if ($blocking) {
					return true;
				} else {
					$found = true;
				}
			}
		}
	}

	return $found;
}

function cascading_include($file, $blocking = false) {
	global $CONFIG;
	global $PARAMS;

	$found = false;

	if (isset($CONFIG['monka.path.includes']) && is_array($CONFIG['monka.path.includes'])) {
		foreach ($CONFIG['monka.path.includes'] as $path) {
			$path = trim($path);

			if (is_file(realpath($path.'/'.$file))) {
				include realpath($path.'/'.$file);

				if ($blocking) {
					return true;
				} else {
					$found = true;
				}
			}
		}
	}

	return $found;
}

function cascading_include_once($file, $blocking = false) {
	global $CONFIG;
	global $PARAMS;

	$found = false;

	if (isset($CONFIG['monka.path.includes']) && is_array($CONFIG['monka.path.includes'])) {
		foreach ($CONFIG['monka.path.includes'] as $path) {
			$path = trim($path);

			if (is_file(realpath($path.'/'.$file))) {
				include_once realpath($path.'/'.$file);

				if ($blocking) {
					return true;
				} else {
					$found = true;
				}
			}
		}
	}

	return $found;
}

#
# SCOPED INCLUDE/REQUIRE
#
function scoped_require($__file, $__scope) {
	global $CONFIG;
	global $PARAMS;

	if (is_array($__scope)) {
		extract($__scope);
	} else {
		$data = $__scope;
	}

	require $__file;
}

function scoped_require_once($__file, $__scope) {
	global $CONFIG;
	global $PARAMS;

	if (is_array($__scope)) {
		extract($__scope);
	} else {
		$data = $__scope;
	}

	require_once $__file;
}

function scoped_include($__file, $__scope) {
	global $CONFIG;
	global $PARAMS;

	if (is_array($__scope)) {
		extract($__scope);
	} else {
		$data = $__scope;
	}

	include $__file;
}

function scoped_include_once($__file, $__scope) {
	global $CONFIG;
	global $PARAMS;

	if (is_array($__scope)) {
		extract($__scope);
	} else {
		$data = $__scope;
	}

	include_once $__file;
}

#
# CONFIG HELPERS
#
function add_include_path($path) {
	return append_include_path($path);
}

function append_include_path($path) {
	global $CONFIG;

	if (!is_dir($path)) {
		return false;
	}

	if (!(isset($CONFIG['monka.path.includes']) && is_array($CONFIG['monka.path.includes']))) {
		$CONFIG['monka.path.includes'] = array();
	}

	$CONFIG['monka.path.includes'][] = $path;

	return true;
}

function insert_include_path($path, $position = 0) {
	global $CONFIG;

	if (!is_dir($path)) {
		return false;
	}

	$items = $CONFIG['monka.path.includes'];

	array_splice($items, $position, 0, $path);

	$CONFIG['monka.path.includes'] = $items;

	return true;
}

function rebuild_include_paths($paths = array()) {
	global $CONFIG;

	$paths[] = './';
	$paths[] = dirname(__FILE__);

	$CONFIG['monka.path.includes'] = $paths;
}

#
# IS HELPERS
#
function is_ip($value) {
	if (!ip2long($value)) {
		return false;
	}

	return true;
}

function is_email($value) {
	$valid = false;

	if (eregi('^([_a-z0-9-]+)(\.[_a-z0-9-]+)*@([a-z0-9-]+)(\.[a-z0-9-]+)*(\.[a-z]{2,4})$', $value)) {
		list($username, $domaintld) = split('@', $value);

		if (getmxrr($domaintld, $mxrecords)) {
			$valid = true;
		}
	}

	return $valid;
}

function is_domain($value) {
	$valid = false;

	if (eregi('^([a-z0-9-]+)(\.[a-z0-9-]+)*(\.[a-z]{2,4})$', $value)) {
		if (getmxrr($value, $mxrecords)) {
			return true;
		}
	}

	return $valid;
}

function is_local_url($url) {
	return substr($url, 0, 1) == '/';
}

function is_http_url($url) {
	$url = @parse_url($url);

	if (!$url) {
		return false;
	}

	return in_array($url['scheme'], array('http', 'https'));
}

function is_empty_string($value) {
	return !(isset($value) && trim($value) != '');
}

#
# PAGE
#
function page_exists($page, $blocking = true) {
	global $CONFIG;

	$found = false;

	if (isset($CONFIG['monka.path.includes']) && is_array($CONFIG['monka.path.includes'])) {
		foreach ($CONFIG['monka.path.includes'] as $path) {
			$path = trim($path);

			if (is_file(realpath($path.'/__p.'.$page.'.php'))) {
				if ($blocking) {
					return true;
				} else {
					$found = true;
				}
			}
		}
	}

	return $found;
}

function page($page, $data = array(), $blocking = true) {
	global $CONFIG;

	$found = false;

	if (isset($CONFIG['monka.path.includes']) && is_array($CONFIG['monka.path.includes'])) {
		foreach ($CONFIG['monka.path.includes'] as $path) {
			$path = trim($path);

			if (is_file(realpath($path.'/__p.'.$page.'.php'))) {
				scoped_include(realpath($path.'/__p.'.$page.'.php'), $data);

				if ($blocking) {
					return true;
				} else {
					$found = true;
				}
			}
		}
	}

	return $found;
}

function page_once($page, $data = array(), $blocking = true) {
	global $CONFIG;

	$found = false;

	if (isset($CONFIG['monka.path.includes']) && is_array($CONFIG['monka.path.includes'])) {
		foreach ($CONFIG['monka.path.includes'] as $path) {
			$path = trim($path);

			if (is_file(realpath($path.'/__p.'.$page.'.php'))) {
				scoped_include_once(realpath($path.'/__p.'.$page.'.php'), $data);

				if ($blocking) {
					return true;
				} else {
					$found = true;
				}
			}
		}
	}

	return $found;
}

#
# PARTIALS
#
function render($partial, $data = array(), $blocking = true) {
	global $CONFIG;

	$found = false;

	if (isset($CONFIG['monka.path.includes']) && is_array($CONFIG['monka.path.includes'])) {
		foreach ($CONFIG['monka.path.includes'] as $path) {
			$path = trim($path);

			if (is_file(realpath($path.'/__t.'.$partial.'.php'))) {
				scoped_include(realpath($path.'/__t.'.$partial.'.php'), $data);

				if ($blocking) {
					return true;
				} else {
					$found = true;
				}
			}
		}
	}

	return $found;
}

function render_once($partial, $data = array(), $blocking = true) {
	global $CONFIG;

	$found = false;

	if (isset($CONFIG['monka.path.includes']) && is_array($CONFIG['monka.path.includes'])) {
		foreach ($CONFIG['monka.path.includes'] as $path) {
			$path = trim($path);

			if (is_file(realpath($path.'/__t.'.$partial.'.php'))) {
				scoped_include_once(realpath($path.'/__t.'.$partial.'.php'), $data);

				if ($blocking) {
					return true;
				} else {
					$found = true;
				}
			}
		}
	}

	return $found;
}

#
# SLUG EXCERPT
#
function slug($str) {
	$str = strtolower(trim($str));
	$str = preg_replace('/[^a-z0-9-]/', '-', $str);
	$str = preg_replace('/-+/', "-", $str);

	return $str;
}

function excerpt($text, $max_length = 250) {
	$text = trim($text);

	if ($text != '') {
		if (strlen($text) <= $max_length) {
			return $text;
		}

		return substr($text, 0, $max_length).' [...]';
	}

	return $text;
}

#
# FLAT STORAGE
#
function get_file_data($key) {
	global $CONFIG;

	if (is_empty_string($CONFIG['monka.file_data.dir'])) {
		return false;
	}

	$key = slug($key);
	$path = realpath($CONFIG['monka.file_data.dir'].'/monka.'.$key.'.data');

	if (!is_file($path)) {
		return array();
	}

	return unserialize(file_get_contents($path));
}

function set_file_data($key, $data) {
	global $CONFIG;

	if (is_empty_string($CONFIG['monka.file_data.dir'])) {
		return false;
	}

	$key = slug($key);
	$data = serialize($data);
	$path = $CONFIG['monka.file_data.dir'].'/monka.'.$key.'.data';

	if (dirname($path) != $CONFIG['monka.file_data.dir'] && basename($path) != $key.'.data') {
		return false;
	}

	if (isset($CONFIG['monka.file_data.size']) && is_int($CONFIG['monka.file_data.size'])) {
		if ($CONFIG['monka.file_data.size'] < strlen($data)) {
			return false;
		} else {
			if (!$handle = fopen($path, 'w')) {
				return false;
			}

			if (fwrite($handle, $data) === false) {
				fclose($handle);

				return false;
			}

			fclose($handle);

			return true;
		}
	} else {
		if (!$handle = fopen($path, 'w')) {
			return false;
		}

		if (fwrite($handle, $data) === false) {
			fclose($handle);

			return false;
		}

		fclose($handle);

		return true;
	}
}

#
# USER FLAT STORAGE
#
function get_user_file_data() {
	if (!is_authenticated()) {
		return false;
	}

	return get_file_data('user-'.$_SESSION['user.ID']);
}

function set_user_file_data($data) {
	if (!is_authenticated()) {
		return false;
	}

	return set_file_data('user-'.$_SESSION['user.ID'], $data);
}
